#include<iostream>
using namespace std;
const int N=7; 
int Count[N]={3,0,0,1,0,3,5};//每一张纸币的数量 
int Value[N]={1,2,5,10,20,50,100};//每一张的面额  
int solve(int money) 
{
	
	int num=0;
	for(int i=N-1;i>=0;i--) 
	{
		int c=min(money/Value[i],Count[i]);//每一个所需要的张数 
		money=money-c*Value[i];
		int a=c;
				cout<<Value[i]<<"元"<<a<<"张"<<endl; 
		num+=c;//总张数 
		
	}
	if(money>0) num=-1;
	return num;
}
int main() 
{
	cout<<"请输入所有的钱"<<endl; 
	int money;
	cin>>money;
	int res=solve(money);

	if(res!=-1) cout<<"总纸张"<<res<<endl ;   
	else cout<<"NO"<<endl;
 }
// 1创建两组数据，我们定义了限制值和期望值，希望从中选出几个数据，在满足限制值的情况下，期望值最大。
// 2每次选择当前情况下，在对限制值同等贡献量的情况下，对期望值贡献最大的数据。
// 3把求解的问题分成若干个子问题
// 4对每一子问题求解，得到子问题的局部最优解
// 5把子问题对应的局部最优解合成原来整个问题的一个近似最优解
//时间复杂度分析：
// 当1张100块刚好等于100块时，即限制值刚好等于期望值出现
// 最好时间复杂度O（1）当遍历完之后都没有满足期望值时，出现最坏时间复杂度O（n）综上，平均时间复杂度为O（n）.
// 空间复杂度分析：
// 因为没有开辟新的内存空间，只有变量和两个数组开辟了常数内存空间，所以他们的最好空间复杂度=最坏空间复杂度=平均空间复杂度=O（1）.


